#ifndef MISSION_HEADER
#define MISSION_HEADER

#include <allegro.h>
#include <iostream>
#include <cstring>
#include <vector>
#include "util.h"
#include "joypad.h"
#include "cfgreader.h"

using std::cout;
using std::vector;
using std::string;

#define DUP 0
#define DRIGHT 1
#define DDOWN 2
#define DLEFT 3

class BaseObject {
       protected:
               int x, y, w, h;
               int CFrame, CDir, CntFrame;
               BITMAP* Pic;
       public:
               BaseObject(BITMAP *img, int x, int y, int w, int h);
               
               virtual ~BaseObject() {}
               
               virtual bool Collide(BaseObject* obj);
               
               virtual int GetX() {return x;}
               virtual int GetY() {return y;}          
               virtual int GetH() {return h;}
               virtual int GetW() {return w;}
               
               virtual void SetX(int x) {this->x=x;}
               virtual void SetY(int y) {this->y=y;}    
               virtual void SetPos(int x, int y) {this->x=x;this->y=y;}
               
               virtual void Show() {if(Pic) masked_blit(Pic, doubleBuffer, CFrame*w, CDir*h, x, y, w, h);}
               
               virtual void Update() {}
};

class Player:public BaseObject {
	protected:
		int* Attribute;
		int* Attacks;
		char* callname;
		int* AP;
		
		bool live;
		bool defeated;
		
		ConfigReader* Cfg;
		
		int Ani;
		int Anit;
		
		int PL;
		
		int rx, ry;
		
		int stp;
		int stptm;
		
		BITMAP* upst;
		BITMAP* dnst;
		
		BITMAP* slash_a;
		BITMAP* blueball_a;
		BITMAP* fire_a;
		BITMAP* leaf_a;
		BITMAP* scare_a;
		BITMAP* hit_a;
		BITMAP* fist_a;
	
	public:
		enum {
			HP=0,
			MAXHP=1,
			ATTACK=2,
			DEFENSE=3,
			RANGEATK=4,
			RANGEDEF=5,
			SPEED=6,
			AVOIDANCE=7,
			ATKP=8,
			DEFP=9,
			RATKP=10,
			RDEFP=11,
			SPDP=12,
			TYPE=13,
			LV=14
		};
	
		Player(BITMAP *img, BITMAP *ups, BITMAP *dns, int x, int y, int w, int h, const char* botdata, int ply);
		
		virtual int GetAtk(int value) {return Attacks[value];}
		
		virtual int GetPL() {return PL;}
		
		virtual void STP(int value, int tvalue) {stp=value;stptm=tvalue;}
		virtual int GetSTP() {return stp;}
		virtual void STPA();
		virtual void STPC();
		virtual void STPAC() {stptm--;}
		
		virtual int GetType() {return Attribute[TYPE];}
		
		virtual int GetAni() {return Ani;}
		
		virtual void DmgAni() {Ani=1;Anit=50;}
		virtual void STAni(bool updn=true) {if (updn) {Ani=3;Anit=70;} else {Ani=4;Anit=70;}}
		virtual void DefeatAni() {Ani=2;Anit=40;}
		virtual void AtkAni(int value) {Ani=value;Anit=60;}
		virtual void SetAni(int value) {Ani=value;}
		virtual void TurnAni() {Ani=110;Anit=50;}
		
		virtual int GetAttribute(int att);
		virtual void SetAttribute(int att, int value) {Attribute[att]=value;}
		
		virtual bool GetLive() {return live;}
		
		virtual int GetAP(int att) {return AP[att];}
		virtual void SetAP(int att, int value) {AP[att]=value;}
		virtual void MinAP(int att) {AP[att]--;}
		
		virtual void WaterP(int x, int y);
		virtual void ElectroP(int x, int y, int dx, int dy, int dt=10);
		virtual void SandP(int x, int y, int w=50, int h=50);
		virtual void FlashP(int x, int y);
		
		virtual char* CallName() {return callname;}
		
		virtual void Update();
		
		virtual void Show();
};

class ActionD:public BaseObject {
	protected:
		int* Power;
		int* MXAP;
		int* Acc;
		int* AT;
		int* AK;
		int* AType;
		int* STAUS;
		int* STE;
		
		double RW[12][12];
		
		int phase;
		int ophase;
		int firsta;
		int dly;
		
		int atk1;
		int atk2;
		int matk1;
		int matk2;
		
		bool actend;
		bool nnr;
		bool nnr2;
		
		bool p1rstp;
		bool p2rstp;
		
		Player *tp1;
		Player *tp2;
		
		vector<string> AttackNames;
	public:
		ActionD(BITMAP *img, int x, int y, int w, int h);
		~ActionD();
		
		virtual string AtkNames(int value) {return AttackNames[value];}
		virtual int MaxAP(int value) {return MXAP[value];}
		virtual int Phase() {return phase;}
		virtual int GetStaus(int value) {return STAUS[value];}
		virtual double Effective(int v1, int v2) {return RW[v1][v2];}
		virtual bool TES() {return actend;}
		virtual int NNR();
		virtual void OTS() {actend=false;nnr=false;nnr2=false;}
		virtual int FTurn() {return firsta;}
		virtual int AtkPWR(int value) {return Power[value];}
		virtual int AtkType(int value) {return AType[value];}
		virtual void ActionDmg(Player *atk, Player *def, int atkn, int pl);
		virtual void ActionAtk(Player *p1, Player *p2, int an1, int an2, int man1, int man2);
		virtual void Update();
		virtual void Show() {}
};

class Bar:public BaseObject {
	protected:
		float value, valuev;
		float maxvalue;
		
		Player* Target;
	
	public:
		Bar(BITMAP *img, Player *targ, int x, int y, int w, int h);
			
		virtual void Update();
		
		virtual void Show();
};

class AtkMBtn:public BaseObject {
	protected:
		Player* Target;
		
		int AtkNum;
		int AP;
		int MAP;
		int MNum;
		
		string AtkName;
	
	public:
		AtkMBtn(BITMAP *img, Player *targ, int x, int y, int w, int h, int anum, string atkn, int maxap, int mn);
		
		virtual int GetAtkN() {return AtkNum;}
		
		virtual void Update();
		
		virtual void Show();
};

class MenuSelect:public BaseObject {
	protected:
		AtkMBtn *pa1, *pa2, *pa3, *pa4;
		
		int selected;
		bool focused;
	
	public:
		MenuSelect(BITMAP *img, int x, int y, int w, int h, AtkMBtn *a1, AtkMBtn *a2, AtkMBtn *a3, AtkMBtn *a4);
		
		virtual int Selected() {return selected;}
		
		virtual int AtkSelected();
		
		virtual void Selects(int value);
		
		virtual void Update();
		
		virtual void Show();
};

class BattleMain {
	protected:
		Player *PL1;
		Player *PL2;
		
		Bar *HPB1;
		Bar *HPB2;
		
		ActionD *AD;
		
		AtkMBtn *AMB1;
		AtkMBtn *AMB2;
		AtkMBtn *AMB3;
		AtkMBtn *AMB4;
		MenuSelect *MS;
		
		bool gameOver;
		bool needsRedraw;
		int turn;
		int sdelay, adelay;
		
		int PL1TA;
		int PL2TA;
		int PL1LA;
		int PL2LA;
		
		int firstturn;
		int TmL;
		
		bool Nnr1;
		bool Nnr2;
		
		//BITMAPS
		BITMAP* Character1_P1;
		BITMAP* Character1_P2;
		
		BITMAP* Menu;
		BITMAP* AtkM;
		BITMAP* UpSt;
		BITMAP* DnSt;
		BITMAP* BarSquare;
		BITMAP* BarBorder;
		BITMAP* BG;
		BITMAP* Ground;
		
		//SAMPLES
		SAMPLE* Bgm;
		
		
		Joypad *joypad;
		
	public:
	
		BattleMain() {}
        ~BattleMain();
        
        virtual void BattleInit(const char* plc);
        
        virtual void Bars(int x, int y, Bar *br, int pl);
              
		virtual void MainLoop();
};

#endif
